package com.hefan.api.service.aop;

import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.cat.common.entity.ResultBean;
import com.cat.common.meta.ResultCode;
import com.cat.common.util.GuuidUtil;
import com.hefan.common.point.bean.BuriedPointVo;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by lxw on 2016/11/18.
 */
@Consumes
public class ApiLogPrintAspect {

    private Logger logger = LoggerFactory.getLogger(ApiLogPrintAspect.class);

    public Object reqParamsLogPrint(ProceedingJoinPoint joinPoint) {
        long beginTime = System.currentTimeMillis();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        Object restObj = null;
        // 传递logId
        String logId = GuuidUtil.getUuid();
        try {
            RpcContext.getContext().setAttachment("logId", logId);
            restObj = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long endTime = System.currentTimeMillis();

        logCollection(logId, request, restObj, beginTime, endTime);

        return restObj;
    }

    /**
     * 获取请求ip地址
     */
    private String getIpAdress(HttpServletRequest request) {
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return ipAddress;
    }

    /**
     * API接口日志收集
     *
     * @param requestId
     * @param request
     * @param resultObj
     * @param beginTime
     * @param endTime
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void logCollection(String requestId, HttpServletRequest request, Object resultObj, long beginTime,
                               long endTime) {
        try {
            Map logMap = new HashMap();
            String url = request.getRequestURL().toString();
            String[] urlArr = url.split("/");
            String apiName = "";
            if (null != urlArr && urlArr.length > 0)
                apiName = urlArr[urlArr.length - 1];
            logMap.put("q_req_id", requestId);
            logMap.put("q_action", "stat_" + apiName);
            logMap.put("q_action_detail", url);
            logMap.put("q_opt_time", beginTime);
            logMap.put("q_opt_duration", (endTime - beginTime));
            logMap.put("q_req_param", request.getParameterMap());
            logMap.put("q_opt_result",
                    (resultObj == null ? new ResultBean(ResultCode.RturnNullException, null) : resultObj));

            String headerStr = request.getHeader("buriedPoint");
            if (StringUtils.isNotBlank(headerStr)) {
                BuriedPointVo headers = JSON.parseObject(headerStr, BuriedPointVo.class);
                logMap.put("q_uid", headers.getUid());
                logMap.put("q_app_ver", headers.getAppVer());
                logMap.put("q_app_code", headers.getAppCode());
                logMap.put("q_channel", headers.getChannelNo());
                logMap.put("q_dev_type", headers.getDeviceType());
                logMap.put("q_dev_model", headers.getDeviceModel());
                logMap.put("q_dev_imei", headers.getDevImei());
                logMap.put("q_sys_version", headers.getSysVersion());
                logMap.put("q_net", headers.getNetType());
                logMap.put("q_ip", (StringUtils.isBlank(headers.getcIp()) ? getIpAdress(request) : headers.getcIp()));
                logMap.put("q_loc", headers.getLoc());
            }
            logger.info(JSON.toJSONString(logMap));
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error("分析日志收集失败" + ex.getMessage());
        }
    }
}
